package de.nak.notendb.action;

import java.util.ArrayList;
import java.util.List;

import com.opensymphony.xwork2.Action;

import de.nak.notendb.model.ExaminationResult;
import de.nak.notendb.model.ExaminationSubject;
import de.nak.notendb.model.OralExaminationResult;
import de.nak.notendb.model.Student;
import de.nak.notendb.service.exceptions.NoExaminationSubjectAvailableException;
import de.nak.notendb.service.exceptions.NoStudentAvailableException;
import de.nak.notendb.service.interfaces.IExaminationResultService;
import de.nak.notendb.service.interfaces.IExaminationSubjectService;
import de.nak.notendb.service.interfaces.IStudentService;

/**
 * The Action to show the History.
 * 
 * @author Christian Baumhof
 * 
 */
public class ShowHistoryAction implements Action {

	/**
	 * The Service to load Students.
	 */
	private IStudentService studentService;

	/**
	 * The Service to load ExaminationSubjects.
	 */
	private IExaminationSubjectService examinationSubjectService;

	/**
	 * The Service to load ExaminationResults.
	 */
	private IExaminationResultService examinationResultService;

	/**
	 * The id of the selected student
	 */
	private Long id;

	/**
	 * The selected Student.
	 */
	private Student selectedStudent;

	/**
	 * The id of the selected Student.
	 */
	private Long selectedSubjectId;

	/**
	 * The displayed list of ExaminationSubjects.
	 */
	private List<ExaminationSubject> subjects;

	/**
	 * The displayed list of ExaminationResults.
	 */
	private List<ExaminationResult> results;

	/**
	 * List of Boolean showing if the corresponding ExaminationResult has a
	 * valid OralExaminationResult
	 */
	private List<Boolean> hasOralExam;

	@Override
	public String execute() throws Exception {
		// load student
		try {
			selectedStudent = studentService.getStudent(id);
		} catch (NoStudentAvailableException exception) {
			return "DATA_NOT_FOUND";
		}

		// load subjects
		try {
			subjects = examinationSubjectService
					.listExaminationSubjects(selectedStudent.getManiple()
							.getId());
		} catch (NoExaminationSubjectAvailableException examination) {
			return "DATA_NOT_FOUND";
		}
		if (selectedSubjectId == null) {
			selectedSubjectId = subjects.get(0).getId();
		}

		// load results
		results = examinationResultService
				.listAllExaminationResultsOfAStudentAndASubject(id,
						selectedSubjectId);

		// initiate hasOralExam
		hasOralExam = new ArrayList<Boolean>();
		for (ExaminationResult result : results) {
			hasOralExam.add(hasOralExam(result));
		}

		return SUCCESS;
	}

	/**
	 * Return the id of the selected Student.
	 * 
	 * @return the id of the selected Student.
	 */
	public Long getSelectedSubjectId() {
		return selectedSubjectId;
	}

	/**
	 * Setter for the id of the selected Student.
	 * 
	 * @param Long
	 *            selectedSubjectId.
	 */
	public void setSelectedSubjectId(Long selectedSubjectId) {
		this.selectedSubjectId = selectedSubjectId;
	}

	/**
	 * Return the selected Student.
	 * 
	 * @return the selected Student.
	 */
	public Student getSelectedStudent() {
		return selectedStudent;
	}

	/**
	 * Return the list of ExaminationSubjects.
	 * 
	 * @return the list of ExaminationSubjects.
	 */
	public List<ExaminationSubject> getSubjects() {
		return subjects;
	}

	/**
	 * Return the list of ExaminationResults.
	 * 
	 * @return the list of ExaminationResults.
	 */
	public List<ExaminationResult> getResults() {
		return results;
	}

	/**
	 * Setter for the StudentService.
	 * 
	 * @param IStudentService
	 *            studentService
	 */
	public void setStudentService(IStudentService studentService) {
		this.studentService = studentService;
	}

	/**
	 * Setter for the ExaminationSubjectService.
	 * 
	 * @param IExaminationSubjectService
	 *            examinationSubjectService.
	 */
	public void setExaminationSubjectService(
			IExaminationSubjectService examinationSubjectService) {
		this.examinationSubjectService = examinationSubjectService;
	}

	/**
	 * Setter for the ExaminationResultService.
	 * 
	 * @param IExaminationResultService
	 *            examinationResultService.
	 */
	public void setExaminationResultService(
			IExaminationResultService examinationResultService) {
		this.examinationResultService = examinationResultService;
	}

	/**
	 * Setter for the id of the selected Student.
	 * 
	 * @param Long
	 *            id.
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * Returns the id of the selected Student.
	 * 
	 * @return the id of the selected Student.
	 */
	public Long getId() {
		return id;
	}

	/**
	 * Returns a list of Boolean showing if the corresponding ExaminationResult
	 * has a valid OralExaminationResult.
	 * 
	 * @return a list of Boolean showing if the corresponding ExaminationResult
	 *         has a valid OralExaminationResult.
	 */
	public List<Boolean> getHasOralExam() {
		return hasOralExam;
	}

	/**
	 * Returns true, if the given ExaminationResult has a valid
	 * OralExaminationResult.
	 * 
	 * @param ExaminationResult
	 *            result
	 * @return true, if the given ExaminationResult has a valid
	 *         OralExaminationResult.
	 */
	private Boolean hasOralExam(ExaminationResult result) {
		if (result.getOralExaminationResults() == null) {
			return false;
		}
		for (OralExaminationResult oralExam : result
				.getOralExaminationResults()) {
			if (oralExam.isValid()) {
				return true;
			}
		}
		return false;
	}

}
